package cn.wapache.time.calendar;

import java.util.TimeZone;

/**
 * 实现Calendar接口的同时,加入了时区
 * @author ykuang
 *
 */
public class BaseCalendar implements Calendar {

    static final long serialVersionUID = 3106623404629760239L;

    private String id;
    private String name;
    private String description;

    private Calendar baseCalendar;

    private TimeZone timeZone;

    ///////////////////////////////////////////////////////////////////////////
    // 构造函数
    ///////////////////////////////////////////////////////////////////////////
    
    public BaseCalendar() {}

    public BaseCalendar(Calendar baseCalendar) {
        setBaseCalendar(baseCalendar);
    }

    public BaseCalendar(TimeZone timeZone) {
        setTimeZone(timeZone);
    }

    public BaseCalendar(Calendar baseCalendar, TimeZone timeZone) {
        setBaseCalendar(baseCalendar);
        setTimeZone(timeZone);
    }

    ///////////////////////////////////////////////////////////////////////////
    // getter setter
    ///////////////////////////////////////////////////////////////////////////
    
    public TimeZone getTimeZone() {
        return timeZone;
    }

    public void setTimeZone(TimeZone timeZone) {
        this.timeZone = timeZone;
    }
    
    ///////////////////////////////////////////////////////////////////////////
    // Calendar接口
    ///////////////////////////////////////////////////////////////////////////

	@Override
	public String getId() {
		return id;
	}

	@Override
	public void setId(String id) {
		if(this.id==null) { this.id = id; }
	}

	@Override
	public String getName() {
		return name;
	}

	@Override
	public void setName(String name) {
		this.name = name;
	}

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Calendar getBaseCalendar() {
    	return this.baseCalendar;
    }

    public void setBaseCalendar(Calendar baseCalendar) {
        this.baseCalendar = baseCalendar;
    }
    
    public boolean isTimeIncluded(long timeStamp) {

        if (timeStamp <= 0) {
            throw new IllegalArgumentException("timeStamp must be greater 0");
        }

        return baseCalendar == null || baseCalendar.isTimeIncluded(timeStamp);
    }

    public long getNextIncludedTime(long timeStamp) {

        if (timeStamp <= 0) {
            throw new IllegalArgumentException("timeStamp must be greater 0");
        }

        if (baseCalendar != null) {
            return baseCalendar.getNextIncludedTime(timeStamp);
        }

        return timeStamp;
    }
    
    @Override
    public Object clone()  {
        try {
            BaseCalendar clone = (BaseCalendar) super.clone();
            if (getBaseCalendar() != null) {
                clone.baseCalendar = (Calendar) getBaseCalendar().clone();
            }
            if(getTimeZone() != null){
                clone.timeZone = (TimeZone) getTimeZone().clone();
            }
            return clone;
        } catch (CloneNotSupportedException ex) {
            throw new IncompatibleClassChangeError("Not Cloneable.");
        }
    }

    
// 移到JdkCalendar去了
//
//    /**
//     * Build a <code>{@link java.util.Calendar}</code> for the given timeStamp.
//     * The new Calendar will use the <code>BaseCalendar</code> time zone if it
//     * is not <code>null</code>.
//     */
//    protected java.util.Calendar createJavaCalendar(long timeStamp) {
//        java.util.Calendar calendar = createJavaCalendar();
//        calendar.setTime(new Date(timeStamp));
//        return calendar;
//    }
//
//    /**
//     * Build a <code>{@link java.util.Calendar}</code> with the current time.
//     * The new Calendar will use the <code>BaseCalendar</code> time zone if
//     * it is not <code>null</code>.
//     */
//    protected java.util.Calendar createJavaCalendar() {
//        return
//            (getTimeZone() == null) ?
//                java.util.Calendar.getInstance() :
//                java.util.Calendar.getInstance(getTimeZone());
//    }
//
//    /**
//     * Returns the start of the given day as a <code>{@link java.util.Calendar}</code>.
//     * This calculation will take the <code>BaseCalendar</code>
//     * time zone into account if it is not <code>null</code>.
//     *
//     * @param timeInMillis A time containing the desired date for the
//     *                     start-of-day time
//     * @return A <code>{@link java.util.Calendar}</code> set to the start of
//     *         the given day.
//     */
//    protected java.util.Calendar getStartOfDayJavaCalendar(long timeInMillis) {
//        java.util.Calendar startOfDay = createJavaCalendar(timeInMillis);
//        startOfDay.set(java.util.Calendar.HOUR_OF_DAY, 0);
//        startOfDay.set(java.util.Calendar.MINUTE, 0);
//        startOfDay.set(java.util.Calendar.SECOND, 0);
//        startOfDay.set(java.util.Calendar.MILLISECOND, 0);
//        return startOfDay;
//    }
//
//    /**
//     * Returns the end of the given day <code>{@link java.util.Calendar}</code>.
//     * This calculation will take the <code>BaseCalendar</code>
//     * time zone into account if it is not <code>null</code>.
//     *
//     * @param timeInMillis a time containing the desired date for the
//     *                     end-of-day time.
//     * @return A <code>{@link java.util.Calendar}</code> set to the end of
//     *         the given day.
//     */
//    protected java.util.Calendar getEndOfDayJavaCalendar(long timeInMillis) {
//        java.util.Calendar endOfDay = createJavaCalendar(timeInMillis);
//        endOfDay.set(java.util.Calendar.HOUR_OF_DAY, 23);
//        endOfDay.set(java.util.Calendar.MINUTE, 59);
//        endOfDay.set(java.util.Calendar.SECOND, 59);
//        endOfDay.set(java.util.Calendar.MILLISECOND, 999);
//        return endOfDay;
//    }
}
